package beautiful.butterfly.drds.data_exchange.core.transport.record;

import beautiful.butterfly.drds.data_exchange.core.util.ClassSize;
import beautiful.butterfly.drds.data_exchange.core.util.FrameworkErrorCode;
import com.alibaba.fastjson.JSON;
import common.element.Column;
import common.element.Record;
import common.exception.DataExchangeException;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


public class DefaultRecord implements Record
{

    private static final int RECORD_AVERGAE_COLUMN_NUMBER = 16;

    private List<Column> columnList;

    private int byteSize;

    // 首先是Record本身需要的内存
    private int memorySize = ClassSize.DefaultRecordHead;

    public DefaultRecord()
    {
        this.columnList = new ArrayList<Column>(RECORD_AVERGAE_COLUMN_NUMBER);
    }


    public void addColumn(Column column)
    {
        columnList.add(column);
        incrByteSize(column);
    }

    public void setColumn(int index, final Column column)
    {
        if (index < 0)
        {
            throw DataExchangeException.asDataExchangeException(FrameworkErrorCode.ARGUMENT_ERROR,
                    "不能给index小于0的column设置值");
        }

        if (index >= columnList.size())
        {
            expandCapacity(index + 1);
        }
        //直接将数据填充到那个位置
        decrByteSize(getColumn(index));
        this.columnList.set(index, column);
        incrByteSize(getColumn(index));
    }

    public int getColumnListSize()
    {
        return this.columnList.size();
    }

    public Column getColumn(int index)
    {
        if (index < 0 || index >= columnList.size())
        {
            return null;
        }
        return columnList.get(index);
    }

    public int getByteSize()
    {
        return byteSize;
    }

    public int getMemoryByteSize()
    {
        return memorySize;
    }

    //
    private void incrByteSize(final Column column)
    {
        if (null == column)
        {
            return;
        }

        byteSize += column.getByteSize();

        //内存的占用是column对象的头 再加实际大小
        memorySize = memorySize + ClassSize.ColumnHead + column.getByteSize();
    }

    private void decrByteSize(final Column column)
    {
        if (null == column)
        {
            return;
        }

        byteSize -= column.getByteSize();

        //内存的占用是column对象的头 再加实际大小
        memorySize = memorySize - ClassSize.ColumnHead - column.getByteSize();
    }


    private void expandCapacity(int totalSize)
    {
        if (totalSize <= 0)
        {
            return;
        }

        int needToExpand = totalSize - columnList.size();
        while (needToExpand-- > 0)
        {
            this.columnList.add(null);
        }
    }

    @Override
    public String toString()
    {
        Map<String, Object> json = new HashMap<String, Object>();
        json.put("size", this.getColumnListSize());
        json.put("data", this.columnList);
        return JSON.toJSONString(json);
    }
}
